package esb.chapter2.jbi;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.jbi.JBIException;
import javax.jbi.component.ComponentContext;
import javax.jbi.component.ComponentLifeCycle;
import javax.jbi.messaging.DeliveryChannel;
import javax.jbi.messaging.ExchangeStatus;
import javax.jbi.messaging.MessageExchange;
import javax.jbi.messaging.MessagingException;
import javax.jbi.servicedesc.ServiceEndpoint;
import javax.management.ObjectName;
import javax.xml.namespace.QName;

import org.apache.log4j.Logger;

/**
 * This is the lifecycle used for our HelloJBI component. This lifecycle
 * controlls the init, shutdown, start and stop of our component.
 * @author nl24167
 *
 */
public class HelloJBILifeCycle implements ComponentLifeCycle {

	private static Logger LOG = Logger.getLogger(HelloJBILifeCycle.class);
    private boolean shouldStop = false;	
	private ComponentContext componentContext;
	private DeliveryChannel deliveryChannel;
	private ExecutorService receiverThreadMgr;
	private HelloJBI targetService;

	private ServiceEndpoint endpoint;

	public ObjectName getExtensionMBeanName() {
		return null;
	}

	public void init(ComponentContext componentContext) throws JBIException {
		targetService = new HelloJBI();
		
		this.componentContext = componentContext;
		LOG.info("Initializing component lifecycle: " + componentContext.getComponentName());
		deliveryChannel = componentContext.getDeliveryChannel();
		initMessageExchangeReceiver();
	
		endpoint = componentContext.activateEndpoint(new QName("http://test/","HelloJBI"), "endpointName");
		LOG.info("Endpoint " + endpoint + "registered for " + componentContext.getComponentName());
		}

	public void shutDown() throws JBIException {
		LOG.info("Shutting down component: " + componentContext.getComponentName());
		shouldStop = true;
		componentContext.deactivateEndpoint(endpoint);
		deliveryChannel.close();
	}

	public void start() throws JBIException {
		LOG.info("Starting component: " + componentContext.getComponentName());
	}

	public void stop() throws JBIException {
		LOG.info("Stopping component: " + componentContext.getComponentName());
	}
	
    private void initMessageExchangeReceiver() {
        receiverThreadMgr = Executors.newSingleThreadExecutor();
        receiverThreadMgr.execute(new Runnable() {

			public void run() {
                Thread t = Thread.currentThread();
                while ( !shouldStop ) {  // continue running the thread
                    if (true) { // check for message exchange and process it
                        receiveAndProcessMessageExchange();
                    } else { 
                        try {
                            Thread.sleep(5000);
                        } catch (InterruptedException interruptException) {
                            // ignore
                        }
                    }
                }
            }
        });
    }	
    
    private void receiveAndProcessMessageExchange() {
        try {
             MessageExchange msgExchange = null;
             msgExchange = deliveryChannel.accept(2000);
             if ( msgExchange != null ) {
                 targetService.sayHelloJBI(msgExchange.getMessage("in").getContent());
                 msgExchange.setStatus(ExchangeStatus.DONE);
                 deliveryChannel.send(msgExchange);
                 
                 ServiceEndpoint targetEndpoint = componentContext.getEndpoint(new QName("http://test/","beanservice"), "endpoint");
                 LOG.info("Sending to targetEndpoint: " + targetEndpoint);
                 MessageExchange outExchange = deliveryChannel.createExchangeFactory(targetEndpoint).createInOnlyExchange();
                 outExchange.setMessage(msgExchange.getMessage("in"), "in");
                 deliveryChannel.send(outExchange);
             } else {
                 return;
             }
        } catch (MessagingException ex) {
            ex.printStackTrace();
        }
    }    

}
